package com.fengke.portal.interceptor;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import net.sf.json.JSONObject;

import org.apache.log4j.Logger;
import org.apache.struts2.ServletActionContext;

import com.fengke.dao.model.MemberModel;
import com.fengke.dao.model.OpenUnionModel;
import com.fengke.dao.model.MemberModel.Gender;
import com.fengke.payment.tencent.common.Configure;
import com.fengke.payment.tencent.common.RestHttpRequestHelper;
import com.fengke.service.CacheService;
import com.fengke.service.MemberService;
import com.fengke.service.SystemParamService;
import com.fengke.service.vo.MemberVO;
import com.fengke.service.vo.OpenUnionVO;
import com.fengke.service.vo.WeixinUser;
import com.fengke.util.Constants;
import com.fengke.util.LoggerFactory;
import com.fengke.util.StringUtil;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;

public class WeixinInterceptor extends AbstractInterceptor {
	private static final long serialVersionUID = 1L;
	private Logger logger = LoggerFactory.getLogger(WeixinInterceptor.class);
	private MemberService memberService;
	private SystemParamService systemParamService;
	private CacheService cacheService;

	public String intercept(ActionInvocation invocation) throws Exception {
		String result = null;
		try {
			before(invocation);
			ActionContext ctx = invocation.getInvocationContext();
			HttpServletRequest request = (HttpServletRequest) ctx.get(ServletActionContext.HTTP_REQUEST);
			HttpSession session = request.getSession();
			logger.info("WeixinInterceptor before >>>>>>>>>>>>>>>>>>>>");
			MemberVO memberVO = (MemberVO) session.getAttribute(Constants.SessionProfileName.ESTORE_PROFILE_NAME);
			if (memberVO != null) {
				// 用户信息已存在
				logger.info("WeixinInterceptor 用户信息已存在!memberVO=" + memberVO);
			} else {
				String openId = (String) session.getAttribute(Configure.getAppid() + "openId");
//				if (StringUtil.isEmpty(openId)) {
//					// union_id = o2WmotzkMBqoa1Poy5wIHgTsBGA4
//					// open_id = oV7OwjvXfAjrXP-hjXMDcSS6NGPY
//					openId = "oV7OwjvXfAjrXP-hjXMDcSS6NGPY";
//				}
				logger.info("WeixinInterceptor 用户信息memberVO不存在!openId=" + openId);
				if (!StringUtil.isEmpty(openId)) {
					// Session中存在OpenId
					OpenUnionVO openUnionVO = null;
					try {
						openUnionVO = memberService.researchOpenUnionByOpenId(openId);
					} catch (Exception e) {
						logger.error("researchOpenUnionByOpenId Exception! openId = " + openId, e);
					}
					if (openUnionVO != null && openUnionVO.getOpenUnionModel() != null && !StringUtil.isEmpty(openUnionVO.getOpenUnionModel().getUnionId())) {
						try {
							memberVO = memberService.researchMemberByUnionId(openUnionVO.getOpenUnionModel().getUnionId());
							if(memberVO != null && memberVO.getMemberModel() != null) {
								memberVO.getMemberModel().setOpenId(openUnionVO.getOpenUnionModel().getOpenId());
								session.setAttribute(Constants.SessionProfileName.ESTORE_PROFILE_NAME, memberVO);
							} else {
								// 获取微信用户信息
								this.handleWeixin(request);
							}
						} catch (Exception e) {
							logger.error("researchMemverByUnionId Exception! openUnionVO = " + openUnionVO, e);
							// 获取微信用户信息
							this.handleWeixin(request);
						}
					} else {
						// 获取微信用户信息
						this.handleWeixin(request);
					}
				} else {
					// Session中不存在OpenId
					// 获取微信用户信息
					this.handleWeixin(request);
				}
			}
			logger.info("WeixinInterceptor after >>>>>>>>>>>>>>>>>>>>");

			result = invocation.invoke();
			after(invocation, result);
		} catch (Exception e) {
			logger.error("WeixinInterceptor global Exception!", e);
		}
		return result;
	}

	// 获取微信用户信息
	private void handleWeixin(HttpServletRequest request) {
		String code = request.getParameter("code");
		if(StringUtil.isEmpty(code)) {
			return;
		}
		logger.info(this.getClass().getName() + ",handleWeixin, Code = " + code);
		// TODO 调用接口程序
		Map<String, String> paramMap = new HashMap<String, String>();
		paramMap.put("appid", Configure.getAppid());
		paramMap.put("secret", Configure.getAppSecret());
		paramMap.put("code", code);
		paramMap.put("grant_type", Configure.getGrant_type());
		String restRequest = RestHttpRequestHelper.executeHttpRequest(Configure.WX_OAUTH2_URL, paramMap);
		logger.info("WX_OAUTH2_URL restRequest=" + restRequest);
		JSONObject jsonObject = JSONObject.fromObject(restRequest);
		logger.info("jsonObject=" + jsonObject);
		String openId = (String) jsonObject.get("openid");
		String access_token = (String) jsonObject.get("access_token");
		String refresh_token = (String) jsonObject.get("refresh_token");
		
		logger.info(this.getClass().getName() + ",handleWeixin, openId:" + openId + ", refresh_token:" + refresh_token);
		if (openId != null && access_token != null && refresh_token != null) {
			// 校验access_token
//			Map<String, String> checkParamMap = new HashMap<String, String>();
//			checkParamMap.put("access_token ", access_token);
//			checkParamMap.put("openid", openId);
//			String checkResponse = RestHttpRequestHelper.executeHttpRequest("https://api.weixin.qq.com/sns/auth", checkParamMap);
//			JSONObject checkJsonObject = JSONObject.fromObject(checkResponse);
//			String checkErrcode = checkJsonObject.getString("errcode");
//			if(!"0".equals(checkErrcode)) {
//				logger.error("checkJsonObject access_token 无效！checkResponse=" + checkResponse);
//			}
			
			// 刷新access_token
//			Map<String, String> refreshParamMap = new HashMap<String, String>();
//			refreshParamMap.put("appid", Configure.getAppid());
//			refreshParamMap.put("grant_type", "refresh_token");
//			refreshParamMap.put("refresh_token", refresh_token);
//			String refreshResponse = RestHttpRequestHelper.executeHttpRequest(Configure.WX_OAUTH2_REFRESH_TOKEN_URL, refreshParamMap);
//			logger.info("WX_OAUTH2_REFRESH_TOKEN_URL refreshResponse=" + refreshResponse);
//			JSONObject refreshJsonObject = JSONObject.fromObject(refreshResponse);
//			logger.info("refreshJsonObject" + refreshJsonObject);
//			access_token = (String) refreshJsonObject.get("access_token");
			
			request.getSession().setAttribute(Configure.getAppid() + "openId", openId);
			String unionid = null;
			WeixinUser weixinUser = null;
			OpenUnionVO openUnionVO = null;
			try {
				openUnionVO = memberService.researchOpenUnionByOpenId(openId);
			} catch (Exception e) {
				logger.error("handleWeixin researchOpenUnionByOpenId Exception! openId=" + openId, e);
			}
			// unionid存自己服务器减少调用微信的次数
			if (openUnionVO != null && openUnionVO.getOpenUnionModel() != null) {
				unionid = openUnionVO.getOpenUnionModel().getUnionId();
			} else {
				weixinUser = this.getWeixinUser(openId, access_token);
				logger.info("handleWeixin weixinUser" + weixinUser);
				logger.info("handleWeixin nickname" + weixinUser.getNickname());
				logger.info("handleWeixin unionid" + weixinUser.getUnionid());
				unionid = weixinUser.getUnionid();
				
				openUnionVO = new OpenUnionVO();
				OpenUnionModel newOpenUnion = new OpenUnionModel();
				newOpenUnion.setOpenId(openId);
				newOpenUnion.setUnionId(unionid);
				newOpenUnion.setCreateDate(new Date());
				newOpenUnion.setModifyDate(new Date());
				openUnionVO.setOpenUnionModel(newOpenUnion);
				try {
					openUnionVO.getOpenUnionModel().setId(memberService.createOpenUnion(openUnionVO));;
				} catch (Exception e) {
					logger.error("handleWeixin createOpenUnion Exception! openUnionVO=" + openUnionVO, e);
				}
				try {
					cacheService.invalidMasterCache();
				} catch (Exception e) {
					logger.error("handleWeixin invalidOpenUnionCache Exception!", e);
				}
			}
			if (unionid == null) {
				logger.info("请把公众账号与开放平台绑定");
				return;
			}

			logger.info("unionid:" + unionid);
			request.getSession().setAttribute(Configure.getAppid() + "unionId", unionid);
			MemberVO member = null;
			try {
				member = memberService.researchMemberByUnionId(unionid);
			} catch (Exception e) {
				logger.error("handleWeixin researchMemberByUnionId Exception! unionid=" + unionid, e);
			}
			logger.info("handleWeixin member:" + member);

			if (member != null && member.getMemberModel() != null && openUnionVO != null && openUnionVO.getOpenUnionModel() != null) {
				member.getMemberModel().setOpenId(openUnionVO.getOpenUnionModel().getOpenId());
				request.getSession().setAttribute(Constants.SessionProfileName.ESTORE_PROFILE_NAME, member);
			} else {
				// 根据unionid获取用户信息
				if(weixinUser == null) {
					weixinUser = this.getWeixinUser(openId, access_token);
				}
				MemberVO newMemberVO = new MemberVO();
				MemberModel newMember = new MemberModel();
				newMember.setUsername(weixinUser.getNickname());
				newMember.setPassword("000000");
				if (weixinUser != null && weixinUser.getSex() == "1") {
					newMember.setGender(Gender.male);
				} else {
					newMember.setGender(Gender.female);
				}
				newMember.setHeadImgUrl(weixinUser.getHeadimgurl());
				newMember.setHometown(weixinUser.getCountry() + "," + weixinUser.getProvince() + "," + weixinUser.getCity());

				newMember.setPoint(0l);
				newMember.setIsEnabled(true);
				newMember.setAmount(new BigDecimal(0l));
				newMember.setBalance(new BigDecimal(0l));
				newMember.setUnionId(weixinUser.getUnionid());
				newMember.setCreateDate(new Date());
				newMember.setModifyDate(new Date());
				newMemberVO.setMemberModel(newMember);

				try {
					newMemberVO.getMemberModel().setId(memberService.createMember(newMemberVO));;
				} catch (Exception e) {
					logger.error("handleWeixin createMember Exception! newMemberVO=" + newMemberVO, e);
				}
				try {
					cacheService.invalidMemberCache();
				} catch (Exception e) {
					logger.error("handleWeixin invalidMemberCache Exception!", e);
				}
				request.getSession().setAttribute(Constants.SessionProfileName.ESTORE_PROFILE_NAME, newMemberVO);
			}
		} else {
			logger.error("openId OR refresh_token is null");
		}
	}

	public WeixinUser getWeixinUser(String openid, String access_token) {
		Map<String, String> paramMap = new HashMap<String, String>();
		paramMap.put("access_token", access_token);
		paramMap.put("openid", openid);
		paramMap.put("lang", "zh_CN");
		
		String json = RestHttpRequestHelper.executeHttpRequest(Configure.WX_OAUTH2_USERINFO, paramMap);
		logger.info("getWeixinUser userJson=" + json);
		
		if (json != null) {
			JSONObject userJsonObject = JSONObject.fromObject(json);
			WeixinUser user = new WeixinUser();
			user.setOpenid(userJsonObject.getString("openid"));
			user.setNickname(userJsonObject.getString("nickname"));
			user.setSex(userJsonObject.getString("sex"));
			user.setProvince(userJsonObject.getString("province"));
			user.setCity(userJsonObject.getString("city"));
			user.setCountry(userJsonObject.getString("country"));
			user.setHeadimgurl(userJsonObject.getString("headimgurl"));
			user.setUnionid(userJsonObject.getString("unionid"));
			
			return user;
		}
		return null;
	}

	private void after(ActionInvocation invocation, String result) {
		logger.info("after >>>>>>>>>>>>>>>>>>>>>");
	}

	private void before(ActionInvocation invocation) {
		logger.info("before >>>>>>>>>>>>>>>>>>>>");
	}

	public MemberService getMemberService() {
		return memberService;
	}

	public void setMemberService(MemberService memberService) {
		this.memberService = memberService;
	}

	public SystemParamService getSystemParamService() {
		return systemParamService;
	}

	public void setSystemParamService(SystemParamService systemParamService) {
		this.systemParamService = systemParamService;
	}

	public CacheService getCacheService() {
		return cacheService;
	}

	public void setCacheService(CacheService cacheService) {
		this.cacheService = cacheService;
	}

}
